06 Code splitting e Lazy loading

Próxima Atividade
  • Sugerir melhoria
Play
Current Time 0:00
/
Duration Time 0:00
Remaining Time -0:00
Stream TypeLIVE
Loaded: 0%
Progress: 0%
0:00
Fullscreen
00:00
Mute
Playback Rate
  • 2x
  • 1.5x
  • 1.2x
  • 1x
  • 0.8x
  • 0.7x
1x
Subtitles
  • subtitles off
Captions
  • captions off
Chapters
  • Chapters
HD

Transcrição

A aplicação que estamos utilizando para trabalhar com Webpack é o protótipo de um single page application. Nós sabemos que é normal utilizar frameworks do mercado em aplicações deste tipo, como Angular e React.

No entanto, existe algo que devemos considerar. Você percebeu que todos os módulos da aplicação ficarão no bundle.js, ou seja, em um único arquivo? Isto significa que se a aplicação tiver muitos módulos, o bundle.js vai ficar imenso.

No entanto, isto não é bom. Nós evitamos o problema de fazer múltiplas requisições para fazermos o download de vários arquivos. Mas, agora, gastamos um bom tempo para baixar o bundle.js e para só então, ele será processado pela aplicação.

Um estratégia utilizada para a resolução de problemas como esse é o code splitting (separação de código) e o lazy loading (carregamento preguiçoso). Em aplicação como AngularJS ou VueJS, em seus sistemas de rotas, podemos informar que queremos carregar um módulo no momento em que for necessário.

A aplicação não será carregada com esse módulo, ele ficará em back-end separado, e quando acessarmos o módulo pela primeira vez, ele será carregado pelo framework uma única vez.

Desta forma, se queremos fazer um carregamento sob demanda (lazy loading), devemos ter a aplicação divida em partes menores. Para o escopo do projeto, vamos escolher esse módulo - que define a classe NegociacaoService.js - para ser a parte carregada sob demanda.

Com isso, o Webpack saberá que no momento da criação dos bundles, será gerado um arquivo bundle para a aplicação e outro separado destinado ao módulo carregado sob demanda.

Estes conceitos serão utilizados se você trabalha com AngularJS e React, ainda que existam alguns detalhes específicos de quando estes fazem o lazy loading. Mas é isso que faremos basicamente.

Primeiramente, levaremos em conta que não deve haver na nossa aplicação um import estático do módulo NegociacaoService. Sabemos que nesta aplicação, temos o index.js dentro de domain. Neste arquivo, estamos exportando o NegociacoesService.js:

export * from './negociacao/Negociacao.js';
export * from './negociacao/NegociacaoDao.js';
export * from './negociacao/NegociacaoService.js';
export * from './negociacao/Negociacoes.js';

Esta é uma técnica que chamamos de barrel. Nós removeremos o export referente ao NegociacaoService, depois, faremos o mesmo em NegociacaoController.js. No caso, dentro do primeiro import:

import { Negociacoes, Negociacao } from '../domain';
import { NegociacoesView, MensagemView, Mensagem, DateConverter } from '../ui';
import { getNegociacaoDao, Bind, getExceptionMessage, debounce, controller, bindEvent } from '../util';

Vamos removê-lo porque apagaremos todas as importações estáticas do módulo realizadas em nossa aplicação. Como retiramos o import, removeremos também o atributo service responsável pela criação da instância de NegociacaoService(). Logo abaixo do this._mensagem, removeremos this._service.

this._service = new NegociacaoService();

Em seguida, no método importaNegociacoes(), acessamos o service apesar de não existir mais a propriedade da classe, logo, teremos que criar a variável. A seguir, nós usaremos o destructuring do ECMAScript 6 para importar o NegociacaoService, que receberá o resultado de await System.import(). E dentro dos parênteses, passaremos o caminho do módulo.


@bindEvent('click', '#botao-importa')
@debounce()
async importaNegociacoes() {

try {
        const { NegociacaoService } = await System.import('../domain/negociacao/NegociacaoService');

        const service = new NegociacaoService();

        const negociacoes = await service.obtemNegociacoesDoPeriodo();
        console.log(negociacoes);
        negociacoes.filter(novaNegociacao =>

            !this._negociacoes.paraArray().some(negociacaoExistente =>
                novaNegociacao.equals(negociacaoExistente)))
            .forEach(negociacao => this._negociacoes.adiciona(negociacao));

        this._mensagem.texto = 'Negociações do período importadas com sucesso';
    } catch (err) {
        this._mensagem.texto = getExceptionMessage(err);
    }
}

Adicionamos ainda ao try, const service.

Como o projeto utilizou o ES8, utilizamos o async await, com isso podemos chamar um método que seja assíncrono, e esperar o seu resultado.

Se você quer se aprofundar nesta sintaxe, pode fazer o curso de Typescript da Alura.

Agora é possível realizar o carregamento "preguiçoso", com o System.import() - que é disponibilizado pelo Webpack. Você pode se perguntar sobre a maneira como estamos fazendo lazy loading do módulo NegociacaoService. Ele será carregado pela primeira vez, em seguida, será utilizado pela variável, depois, quando chamarmos o mesmo método, o módulo não será mais recarregado e o System.import não será feito novamente.

Porém, como será feita a separação por bundles diferentes?

Se fizermos o build de desenvolvimento no Terminal, o Webpack criará dois novos arquivos dentro da pasta dist: bundle.js e 0.bundle.js.

novos arquivos bundle criados

No arquivo 0.bundle.js, encontraremos o módulo que será carregado primeiramente, por meio do lazy loading. Ao perceber que está sendo realizada a importação dinâmica do módulo, o Webpack sabe quem deverá ser isolado no novo bundle, gerando o código perfeito.

Feito isso, não precisamos nos preocupar em importar o arquino no index.html. Após rodarmos o comando npm start no Terminal, veremos que a aplicação está rodando normalmente. Se abrirmos o Inspect e acessarmos a aba "Network", na primeira vez que a página for carregada, o arquivo 0.bundle.js não será listado. Em seguida, quando clicarmos no botão "Importar Negociações", o arquivo já será baixado na aplicação.

aba netowork com arquivo 0 bundle

Esta forma de fazer carregamento preguiçoso e com códigos separados é bastante adotada em single pages applications. O sucesso do funcionamento dos frameworks depende do bom uso do Webpack.

Tirar dúvida Próxima Atividade
ícone Webpack: Manipulando módulos na sua webapp

Webpack: Manipulando módulos na sua webapp

100%
Aula06 de 06

Boas práticas

Atividades 6 de 16

  • 01 Otimizando o build com Scope Hoisting 03min
  • 02 Resumo
  • 03 Separando o nosso código das bibliotecas 08min
  • 04 CommonsChunkPlugin
  • 05 Gerando a página principal automaticamente 09min
  • 06 Code splitting e Lazy loading 09min
  • 07 System.import vs import 04min
  • 08 Sobre code splitting e lazy loading
  • 09 Quais são os arquivos para distribuição? 02min
  • 10 Alterando o endereço da API no build de produção 08min
  • 11 API de desenvolvimento e de produção
  • 12 O que aprendemos?
  • 13 Consolidando seu conhecimento
  • 14 Considerações finais 01min
  • 15 Download do projeto final
  • 16 Entendendo o que fizemos

Aulas

Outros Links

Fórum Trocar Curso
Gravatar de Marcos Katsumi Kay

Marcos Katsumi Kay 34.0k xp

Logo da Alura